/*
Modifications made by: Paul Stelly & Ricardo Colas
Additions for Project 3: 
int Find(char *name);
void List2();

Modifications for Project 3:
void List();
*/

// filesys.cc 
//	Routines to manage the overall operation of the file system.
//	Implements routines to map from textual file names to files.
//
//	Each file in the file system has:
//	   A file header, stored in a sector on disk 
//		(the size of the file header data structure is arranged
//		to be precisely the size of 1 disk sector)
//	   A number of data blocks
//	   An entry in the file system directory
//
// 	The file system consists of several data structures:
//	   A bitmap of free disk sectors (cf. bitmap.h)
//	   A directory of file names and file headers
//
//      Both the bitmap and the directory are represented as normal
//	files.  Their file headers are located in specific sectors
//	(sector 0 and sector 1), so that the file system can find them 
//	on bootup.
//
//	The file system assumes that the bitmap and directory files are
//	kept "open" continuously while Nachos is running.
//
//	For those operations (such as Create, Remove) that modify the
//	directory and/or bitmap, if the operation succeeds, the changes
//	are written immediately back to disk (the two files are kept
//	open during all this time).  If the operation fails, and we have
//	modified part of the directory and/or bitmap, we simply discard
//	the changed version, without writing it back to disk.
//
// 	Our implementation at this point has the following restrictions:
//
//	   there is no synchronization for concurrent accesses
//	   files have a fixed size, set when the file is created
//	   files cannot be bigger than about 3KB in size
//	   there is no hierarchical directory structure, and only a limited
//	     number of files can be added to the system
//	   there is no attempt to make the system robust to failures
//	    (if Nachos exits in the middle of an operation that modifies
//	    the file system, it may corrupt the disk)
//
// Copyright (c) 1992-1993 The Regents of the University of California.
// All rights reserved.  See copyright.h for copyright notice and limitation 
// of liability and disclaimer of warranty provisions.

#include "copyright.h"

#include "disk.h"
#include "bitmap.h"
#include "directory.h"
#include "filehdr.h"
#include "filesys.h"

// Sectors containing the file headers for the bitmap of free sectors,
// and the directory of files.  These file headers are placed in well-known 
// sectors, so that they can be located on boot-up.
#define FreeMapSector 		0
#define DirectorySector 	1

// Initial file sizes for the bitmap and directory; until the file system
// supports extensible files, the directory size sets the maximum number 
// of files that can be loaded onto the disk.
#define FreeMapFileSize 	(NumSectors / BitsInByte)
#define NumDirEntries 		2
#define DirectoryFileSize 	(sizeof(DirectoryEntry) * NumDirEntries)


//may need to be a bool, what if it already exist.
bool 
FileSystem::addDirToTree(DirectoryEntry* dirToAdd){

	dirTree *leaf = new dirTree;			//used to traverse
	dirTree *newLeaf;						//used to add to the tree
	
	printf("call to add has been made\n");
		
		if(root == NULL){
		//no need to add it, you know its sector and you know its in use, so make a name for it.
		root = leaf;						//allocate memory for the new struct node
		root -> parent = NULL; 				//root has no parent
		root -> child = NULL;				//root is the first thing on tree, therefore no children yet
		root -> sibling = NULL;				//root has no siblings
		root -> dirNode = new DirectoryEntry;
		root -> dirNode->inUse = true;
		root -> dirNode->type = "directory";
		strncpy(root -> dirNode->name, "root", FileNameMaxLen);
		root -> dirNode -> sector = 1;

		printf("the root node has been added name %s with section number %d and type %s\n", root -> dirNode->name,root -> dirNode->sector, root -> dirNode->type);
		currentDirectory = root;			//the current directory is the root directory after root as been created.		
		}
	
	//the current directory is the root directory
	if(currentDirectory == root){					
	
		printf("---------------->root has been established and it is the current directory\n");
		//if the root has no child directories
		if(root->child == NULL){

			leaf -> parent = root;					//set parent directory to the root bro.
			leaf -> child = NULL;					//child of root does not have child yet
			leaf -> sibling = NULL;					//no siblings yet
			leaf -> dirNode = dirToAdd;				//add the entry
			root -> child = leaf;					//connect child directory to the root
					
			printf("child added name %s with section number %d with type %s\n", dirToAdd->name,dirToAdd->sector, dirToAdd->type);
			
			
			
			return true;							//success
			}
		
		//if the current dir is the root and it has a child. so add sibling- traversal needed.
		else if( root->child != NULL){
				
			leaf = root->child;					//used to traverse siblings starting from child.

			while(leaf->sibling != NULL){leaf = leaf->sibling;}		//find the last sibling
				
				newLeaf = new dirTree;				//create the new node to add
				
				newLeaf -> parent = root;			//root is the parent in this case
				newLeaf -> child = NULL;			//no children yet
				newLeaf -> sibling = NULL;			//no other siblings since last to be added
				newLeaf -> dirNode = dirToAdd;		//give node directory data.
				
				leaf -> sibling = newLeaf;			//connect the sibling
				printf("a sibling has been added name %s with section number %d with type %s\n", dirToAdd->name,dirToAdd->sector, dirToAdd->type);
				return true;
				
		}
	}//end of adding from the root 
	else{
	
	//need to find the current dir in the list to know where to add the new node 
		if(currentDirectory->child == NULL){
			
			leaf -> parent = currentDirectory;			//the new directory's parent is the current directory	
			leaf -> child = NULL;					//new directories don't have children
			leaf -> sibling = NULL;					//new child directories dont have siblings
			leaf -> dirNode = dirToAdd;				//add the entry to the list
			currentDirectory -> child = leaf;				//connect child directory to the parent/current Directory.

			return true;							//success			
		}
		else{
		
			leaf = currentDirectory->child;					//used to traverse siblings starting from child.

			while(leaf->sibling != NULL){leaf = leaf->sibling;}		//find the last sibling
				
			newLeaf = new dirTree;							//create the new node to add
			
			newLeaf -> parent = currentDirectory;			//root is the parent in this case
			newLeaf -> child = NULL;				//no children yet
			newLeaf -> sibling = NULL;				//no other siblings since last to be added
			newLeaf -> dirNode = dirToAdd;			//give node directory data.
			
			leaf -> sibling = newLeaf;				//connect the sibling
			
			return true;							//success
		}
	}	
	
}//end of add


//may need to be a bool, how do  you know if it was successful?
bool 
FileSystem::removeFromTree(char* dirToRemove){

	//allocate only when its needed, delete when done.
	dirTree *leaf = new dirTree;			//used to add to the tree
	dirTree *previous = NULL;				//initialize it with something

	//check if the current dir is empty
	if(currentDirectory->child == NULL){
		return false;
	}
	
	//if the child if matched not the sibling.
	if(!strncmp(currentDirectory->child->dirNode->name, dirToRemove, FileNameMaxLen)){  
	
		//strncmp returns 0 if matched from some god awful reason. h8 for C is growing.

		printf("--------->the child matched\n");
		
		//can't remove a directory with a child in it.
		//if(root->child->child != NULL){ 
			//printf("//error, it has a child.\n");
			//printf("%s and %s why\n",root->child->child, currentDirectory->child->child );
			//return false;
		//}
		
		//if there are no siblings of the current directory's child, then simply delete child	
		if(currentDirectory->child->sibling == NULL){	
			delete currentDirectory->child;		//or currentDirectory->child = NULL;
			return true;
		}
		else{ 
			
			printf("//the child dir to be removed has sibling(s)\n");		
			leaf = currentDirectory->child->sibling; 	//store the sibling
			
			currentDirectory->child = leaf;			//now the child of currentDirectory is the sibling.
			
			delete leaf;
			
			return true;
			
		}
		
	} //end if child match
	else{
		//now check if a sibling match
	
	///------>delete this is done correctly
		//leaf = currentDirectory->child;		//store the child as starting pt of the traversal of siblings
		/*	
		while(leaf->sibling != NULL){
			
			//check you find it, then check it has kids
			if(leaf->sibling->dirNode == dirToRemove){
				
				if(leaf->sibling->child != NULL){ return false;} 	// error, sibling has a child
				
				//you matched first sibling and there are no other siblings
				if(previous == NULL && leaf->sibling->sibling == NULL){ delete leaf->sibling; return true;}
				
				//you matched the Nth sibling
				if(previous != NULL){} //hit me in the face with a rock please.
			}
		
			//previous would be == NULL on first iteration
			previous = leaf; 	//if b4 == child then just delete sibling
			leaf = leaf->sibling;
			
		}	
		
	
		//stop if you match or stop if there are none siblings left in the list.
		while(leaf->sibling->dirNode.name != dirToRemove.name || leaf->sibling != NULL){
			previous = leaf; 	//if b4 == child then just delete sibling
			leaf = leaf->sibling;
		}
			
		if(leaf->sibling == NULL){ return false;}			//there were no match. 
		
		if(leaf->sibling->child != NULL){ return false;} 	// error, sibling has a child
		
		if(previous == NULL){
			delete leaf->sibling; 
			return true;
		} //there only exited one sibling
		else{
			previous->sibling = leaf->sibling->sibling; 
			delete leaf->sibling;
			return true;
			}//the previous sibling is now siblings with the sibling of the sibling removed. 
	
		printf("------>at least made it to the else\n");
		*/
		
		previous = currentDirectory->child; 		//previous is child
		leaf = previous->sibling;			//leaf is the 1st siblings
		//Check the other siblings
		while(leaf != NULL){				//while sibling not null
		
			//if you match during traversal of sibling, return leaf	
			if(leaf->dirNode->name == dirToRemove){
			
				if(leaf->child != NULL){return false;}	//check if node matched have children. Can't remove with child.
				
				previous->sibling = leaf->sibling;		//if matched, previous' sibling is now the sibling of the node removed.
				delete leaf;							//clean up, don't need leaf anymore
				return true;							//return true, dir was found
				}	
			previous = leaf;							//now previous is last sibling checked.	
			leaf = leaf->sibling;						//leaf is now the next sibling.
		}
		
	
	}//end of giant else statement

	
	//return false; 	//dir not found.		
	
}//end of remove


//bool now, this will update the currentDirectory in directory.h
bool 
FileSystem::changeDirectory(char* name){

	dirTree *leaf;
	leaf = new dirTree;
	
	leaf = currentDirectory->child;			//leaf is the first child of the currentDirectory
	
	if(leaf->dirNode->name == name){
		currentDirectory = leaf;		//set currentDirectory (the one store in class) to leaf
		//delete leaf;					//clean up, don't need leaf anymore
		return true;					//return true dir was found
	}
	
	
	leaf = leaf->sibling;				//leaf is the first sibling of the current directory's child
	
	//now leaf is the child's first sibling if the child didn't match
	if(leaf->dirNode->name == name){
		currentDirectory = leaf; 		//set currentDirectory(the one store in class) to leaf(firstSibling)
		//delete leaf;					//clean up, don't need leaf anymore
		return true;					//return true dir was found
		}
	
	//Check the other siblings
	while(leaf->sibling != NULL){
	
		//if you match during traversal of sibling, return leaf	
		if(leaf->sibling->dirNode->name == name){
			currentDirectory = leaf->sibling;  	//set currentDirectory(the one store in class) to leaf(firstSibling)
			//delete leaf;						//clean up, don't need leaf anymore
			return true;						//return true, dir was found
			}	
			
		leaf = leaf->sibling;					//leaf is now the next sibling.
	}
	
	delete leaf;		//delete leaf, directory for cd is not found, you don't need it
	return false; 		//return false if the directory is not found

}//end of changeDirectory


//----------------------------------------------------------------------
// FileSystem::FileSystem
// 	Initialize the file system.  If format = TRUE, the disk has
//	nothing on it, and we need to initialize the disk to contain
//	an empty directory, and a bitmap of free sectors (with almost but
//	not all of the sectors marked as free).  
//
//	If format = FALSE, we just have to open the files
//	representing the bitmap and the directory.
//
//	"format" -- should we initialize the disk?
//----------------------------------------------------------------------

FileSystem::FileSystem(bool format)
{ 
printf("--------------format ");
    DEBUG('f', "Initializing the file system.\n");
    if (format) {
        BitMap *freeMap = new BitMap(NumSectors);
        Directory *directory = new Directory(NumDirEntries);
	FileHeader *mapHdr = new FileHeader;
	FileHeader *dirHdr = new FileHeader;

        DEBUG('f', "Formatting the file system.\n");
		
		//root = NULL; 			//initialize root null so the root directory can be added to "tree"

    // First, allocate space for FileHeaders for the directory and bitmap
    // (make sure no one else grabs these!)
	freeMap->Mark(FreeMapSector);	    
	freeMap->Mark(DirectorySector);

    // Second, allocate space for the data blocks containing the contents
    // of the directory and bitmap files.  There better be enough space!

	ASSERT(mapHdr->Allocate(freeMap, FreeMapFileSize));
	ASSERT(dirHdr->Allocate(freeMap, DirectoryFileSize));

    // Flush the bitmap and directory FileHeaders back to disk
    // We need to do this before we can "Open" the file, since open
    // reads the file header off of disk (and currently the disk has garbage
    // on it!).

        DEBUG('f', "Writing headers back to disk.\n");
	mapHdr->WriteBack(FreeMapSector);    
	dirHdr->WriteBack(DirectorySector);

    // OK to open the bitmap and directory files now
    // The file system operations assume these two files are left open
    // while Nachos is running.

        freeMapFile = new OpenFile(FreeMapSector);
        directoryFile = new OpenFile(DirectorySector);
     
    // Once we have the files "open", we can write the initial version
    // of each file back to disk.  The directory at this point is completely
    // empty; but the bitmap has been changed to reflect the fact that
    // sectors on the disk have been allocated for the file headers and
    // to hold the file data for the directory and bitmap.

        DEBUG('f', "Writing bitmap and directory back to disk.\n");
	freeMap->WriteBack(freeMapFile);	 // flush changes to disk
	directory->WriteBack(directoryFile);
	
	//addDirToTree(directory->getTable());			//add the root directory to the "tree"
	
	if (DebugIsEnabled('f')) {
	    freeMap->Print();
	    directory->Print();

        delete freeMap; 
	delete directory; 
	delete mapHdr; 
	delete dirHdr;
	}
    } else {
    // if we are not formatting the disk, just open the files representing
    // the bitmap and directory; these are left open while Nachos is running
        freeMapFile = new OpenFile(FreeMapSector);
        directoryFile = new OpenFile(DirectorySector);
    }
}

//----------------------------------------------------------------------
// FileSystem::Create
// 	Create a file in the Nachos file system (similar to UNIX create).
//	Since we can't increase the size of files dynamically, we have
//	to give Create the initial size of the file.
//
//	The steps to create a file are:
//	  Make sure the file doesn't already exist
//        Allocate a sector for the file header
// 	  Allocate space on disk for the data blocks for the file
//	  Add the name to the directory
//	  Store the new file header on disk 
//	  Flush the changes to the bitmap and the directory back to disk
//
//	Return TRUE if everything goes ok, otherwise, return FALSE.
//
// 	Create fails if:
//   		file is already in directory
//	 	no free space for file header
//	 	no free entry for file in directory
//	 	no free space for data blocks for the file 
//
// 	Note that this implementation assumes there is no concurrent access
//	to the file system!
//
//	"name" -- name of file to be created
//	"initialSize" -- size of file to be created
//----------------------------------------------------------------------

bool
FileSystem::Create(char *name, int initialSize)
{
    Directory *directory;
    BitMap *freeMap;
    FileHeader *hdr, *hdr2 = new FileHeader;
    int sector;
    bool success;
	int newLength, newNumDir;

    DEBUG('f', "Creating file %s, size %d\n", name, initialSize);
    directory = new Directory((directoryFile->Length()/sizeof(DirectoryEntry)));
    directory->FetchFrom(directoryFile);

    if (directory->Find(name) != -1)
      success = FALSE;			// file is already in directory
    else {	
        
		freeMap = new BitMap(NumSectors);	//create a new bitmap
        freeMap->FetchFrom(freeMapFile);	//initialize it with the contents of disk
		freeMap->Print();
        sector = freeMap->Find();			// find a sector to hold the file header
    	
		if (sector == -1)		
            success = FALSE;				// no free block for file header 
			
        else if (!directory->Add(name, sector)){
		
			//begin modification
			newLength = directory->getSize() + 1; 	//new length of the directory file is it's previous length + the size of a Directory Entry

			delete directory;							//delete old directory
			directory = new Directory(newLength);		//make a directory with the new length	
			directory->FetchFrom(directoryFile);		//initialize directory from the contents of disk
		
			hdr2 = directoryFile->getHeader(hdr2,1);	//get the directory file header
			
			newNumDir = newLength * sizeof(DirectoryEntry);		//new size
			
		//printf("newLength is %d, directoryFileSize is %d, newNumDir is %d, sector is %d\n", newLength, DirectoryFileSize, newNumDir, sector); 
		//printf("hdr2->FileLength() is %d\n", hdr2->FileLength());
		
			hdr2->Allocate(freeMap, newNumDir);			//if the allocation of the directoryFile fails(no more space) , return false.
		
		//printf("hdr2->FileLength() is %d\n", hdr2->FileLength());
		
			hdr2->WriteBack(1);							//write the new head to sector reserved for the directory
			
			delete directoryFile;						//clean up
			directoryFile = new OpenFile(1);			//open newly alter directory file from the root directory sector
		
		//printf("before we add the file with newLength of %d\n", newLength);
		
			if(!directory->Add(name, sector))
				success = FALSE;
			//else{addDirToTree(directory->getTable());}
			
			hdr = new FileHeader;
			if (!hdr->Allocate(freeMap, initialSize))
			//end modification
					success = FALSE;	// no space on disk for data

	    else {	
	    	success = TRUE;
		// everthing worked, flush all changes back to disk
			
    	    	hdr->WriteBack(sector);
    	    	directory->WriteBack(directoryFile);
    	    	freeMap->WriteBack(freeMapFile);
				
				

	    }
            delete hdr;
	    delete hdr2;
		}
		

	else {
    	    hdr = new FileHeader;
	    if (!hdr->Allocate(freeMap, initialSize))
		//end modifcation
            	success = FALSE;	// no space on disk for data

	    else {	
	    	success = TRUE;
		// everthing worked, flush all changes back to disk
			
    	    	hdr->WriteBack(sector);
    	    	directory->WriteBack(directoryFile);
    	    	freeMap->WriteBack(freeMapFile);
			
	    }
            delete hdr;
	}
        delete freeMap;
    }
    delete directory;
	if(!success)
	{
		printf("returning false\n");
	} 
    return success;
}

bool FileSystem::AddDir(char *name)
{
	 Directory *directory;
    BitMap *freeMap;
    FileHeader *hdr, *hdr2 = new FileHeader;
    int newSector;
    bool success;
	int newLength, newNumDir;

    DEBUG('f', "Creating directory %s, size %d\n", name);
    directory = new Directory((directoryFile->Length()/sizeof(DirectoryEntry)));
    directory->FetchFrom(directoryFile);

    if (directory->Find(name) != -1)
      success = FALSE;			// file is already in directory
    else {	
        
		freeMap = new BitMap(NumSectors);	//create a new bitmap
        freeMap->FetchFrom(freeMapFile);	//initialize it with the contents of disk
		freeMap->Print();
        newSector = freeMap->Find();			// find a sector to hold the file header
    	
		if (newSector == -1)		
            success = FALSE;				// no free block for file header 
			
        else if (!directory->AddDir(name, newSector)){
		
			//begin modification
			newLength = directory->getSize() + 1; 	//new length of the directory file is it's previous length + the size of a Directory Entry

			delete directory;							//delete old directory
			directory = new Directory(newLength);		//make a directory with the new length	
			directory->FetchFrom(directoryFile);		//initialize directory from the contents of disk
		
			hdr2 = directoryFile->getHeader(hdr2,currentDirectory->dirNode->sector);	//get the directory file header
			
			newNumDir = newLength * sizeof(DirectoryEntry);		//new size
			
			hdr2->Allocate(freeMap, newNumDir);			//if the allocation of the directoryFile fails(no more space) , return false.
			hdr2->WriteBack(currentDirectory->dirNode->sector);							//write the new head to sector reserved for the directory
			
			delete directoryFile;						//clean up
			directoryFile = new OpenFile(currentDirectory->dirNode->sector);			//open newly alter directory file from the root directory sector
		

			if(!directory->AddDir(name, newSector)) success = FALSE;

			
			hdr = new FileHeader;
			if (!hdr->Allocate(freeMap, DirectoryFileSize))
			//end modification
					success = FALSE;	// no space on disk for data

	    else {	
	    	success = TRUE;
		// everthing worked, flush all changes back to disk
			
    	    	hdr->WriteBack(newSector);
    	    	directory->WriteBack(directoryFile);
    	    	freeMap->WriteBack(freeMapFile);
	    }
			delete hdr;
			delete hdr2;
		}
		
	else {
    	    hdr = new FileHeader;
			
			if (!hdr->Allocate(freeMap, DirectoryFileSize))
			//end modifcation
					success = FALSE;	// no space on disk for data

			else {	
				success = TRUE; // everthing worked, flush all changes back to disk					
				hdr->WriteBack(newSector);
				directory->WriteBack(directoryFile);
				freeMap->WriteBack(freeMapFile);		
				}
				
				delete hdr;
			}
			
			delete freeMap;
			
    }
    
	delete directory;
	
	if(!success){
		printf("returning false\n");
	} 
	
    return success;
	
	
	/*Directory *directory = new Directory((directoryFile->Length()/sizeof(DirectoryEntry)));  //create a new directory
	BitMap *freeMap = new BitMap(NumSectors);		//create a new bitmap
	int newSector;
	freeMap->FetchFrom(freeMapFile);				//initialize it with the contents of disk
	
	//need a newSector == -1 condition
	//freeMap->Print();
	newSector = freeMap->Find();						//find a sector to hold the file header director is a file
		
    directory->FetchFrom(directoryFile);			//inialize it from contents from disk
    if(directory->AddDir(name, newSector));			
	{
		directory->WriteBack(directoryFile);
		return TRUE;
	}
	
    delete directory;
	delete freeMap;
	
	return FALSE;*/
}
//----------------------------------------------------------------------
// FileSystem::Open
// 	Open a file for reading and writing.  
//	To open a file:
//	  Find the location of the file's header, using the directory 
//	  Bring the header into memory
//
//	"name" -- the text name of the file to be opened
//----------------------------------------------------------------------

OpenFile *
FileSystem::Open(char *name)
{ 
    Directory *directory = new Directory((directoryFile->Length()/sizeof(DirectoryEntry)));
    OpenFile *openFile = NULL;
    int sector;

    DEBUG('f', "Opening file %s\n", name);
    directory->FetchFrom(directoryFile);
	printf("in open\n");
    sector = directory->Find(name); 
    if (sector >= 0) 		
	openFile = new OpenFile(sector);	// name was found in directory 
    delete directory;
    return openFile;				// return NULL if not found
}



//----------------------------------------------------------------------
// FileSystem::Remove
// 	Delete a file from the file system.  This requires:
//	    Remove it from the directory
//	    Delete the space for its header
//	    Delete the space for its data blocks
//	    Write changes to directory, bitmap back to disk
//
//	Return TRUE if the file was deleted, FALSE if the file wasn't
//	in the file system.
//
//	"name" -- the text name of the file to be removed
//----------------------------------------------------------------------

bool
FileSystem::Remove(char *name)
{ 
    Directory *directory;
    BitMap *freeMap;
    FileHeader *fileHdr, *hdr2 = new FileHeader;
    int sector, newLength, newNumDir;
    
    directory = new Directory((directoryFile->Length()/sizeof(DirectoryEntry)));
    directory->FetchFrom(directoryFile);
    sector = directory->Find(name);
    if (sector == -1) {
       delete directory;
       return FALSE;			 // file not found 
    }
    fileHdr = new FileHeader;
    fileHdr->FetchFrom(sector);

    freeMap = new BitMap(NumSectors);
    freeMap->FetchFrom(freeMapFile);
    fileHdr->Deallocate(freeMap);  		// remove data blocks
    freeMap->Clear(sector);			// remove header block
	directory->Remove(name);
	//begin modification
		newLength = directory->getSize() - 1; //new length of the directory file is it's previous length + the size of a Directory Entry
		delete directory;
		directory = new Directory(newLength);
		directory->FetchFrom(directoryFile);
		hdr2 = directoryFile->getHeader(hdr2,1);
		newNumDir = newLength * sizeof(DirectoryEntry);
		//printf("newLength is %d, directoryFileSize is %d, newNumDir is %d, sector is %d\n", newLength, DirectoryFileSize, newNumDir, sector); 
		//printf("hdr2->FileLength() is %d\n", hdr2->FileLength());
		hdr2->Allocate(freeMap, newNumDir);	//if the allocation of the directoryFile fails(no more space) , return false.
		//printf("hdr2->FileLength() is %d\n", hdr2->FileLength());
		hdr2->WriteBack(1);
		delete directoryFile;
		directoryFile = new OpenFile(1);
		//printf("before we add the file with newLength of %d\n", newLength);
		
	
    freeMap->WriteBack(freeMapFile);		// flush to disk
    directory->WriteBack(directoryFile);        // flush to disk
    delete fileHdr;
    delete directory;
    delete freeMap;
    return TRUE;
}    

//remove a directory if possible
bool FileSystem::RemoveDir(char *name)
{ 
    Directory *directory;
    BitMap *freeMap;
    FileHeader *fileHdr;
    int sector;
    
    directory = new Directory(NumDirEntries);
    directory->FetchFrom(directoryFile);
    sector = directory->Find(name);
    if (sector == -1) {
       delete directory;
       return FALSE;			 // file not found 
    }
    fileHdr = new FileHeader;
    fileHdr->FetchFrom(sector);

    freeMap = new BitMap(NumSectors);
    freeMap->FetchFrom(freeMapFile);

    fileHdr->Deallocate(freeMap);  		// remove data blocks
    freeMap->Clear(sector);			// remove header block
    directory->Remove(name);

    freeMap->WriteBack(freeMapFile);		// flush to disk
    directory->WriteBack(directoryFile);        // flush to disk
    delete fileHdr;
    delete directory;
    delete freeMap;
    return TRUE;
} 


//----------------------------------------------------------------------
// FileSystem::List
// 	List all the files in the file system directory.
//----------------------------------------------------------------------

//Begin Modifications by Paul Stelly and Ricardo Colas
void
FileSystem::List()
{
    Directory *directory = new Directory((directoryFile->Length()/sizeof(DirectoryEntry)));

    directory->FetchFrom(directoryFile);
    directory->List();
    delete directory;
}
//End Modifications by Paul Stelly and Ricardo Colas
//Begin Additions by Paul Stelly and Ricardo Colas
void
FileSystem::List2()
{
    Directory *directory = new Directory((directoryFile->Length()/sizeof(DirectoryEntry)));

    directory->FetchFrom(directoryFile);
    directory->List2();
    delete directory;
}

int
FileSystem::Find(char *name)
{
	Directory *directory = new Directory((directoryFile->Length()/sizeof(DirectoryEntry)));

    directory->FetchFrom(directoryFile);
    int i = directory->Find(name);

    if (i != -1)
	return 1;
    return -1;
}
//End Additions by Paul Stelly and Ricardo Colas

//----------------------------------------------------------------------
// FileSystem::Print
// 	Print everything about the file system:
//	  the contents of the bitmap
//	  the contents of the directory
//	  for each file in the directory,
//	      the contents of the file header
//	      the data in the file
//----------------------------------------------------------------------

void
FileSystem::Print()
{
    FileHeader *bitHdr = new FileHeader;
    FileHeader *dirHdr = new FileHeader;
    BitMap *freeMap = new BitMap(NumSectors);
    Directory *directory = new Directory(NumDirEntries);

   	printf("Bit map file header:\n");
    bitHdr->FetchFrom(FreeMapSector);
    bitHdr->Print();

    printf("Directory file header:\n");
    dirHdr->FetchFrom(DirectorySector);
    dirHdr->Print();

    freeMap->FetchFrom(freeMapFile);
    freeMap->Print();

    directory->FetchFrom(directoryFile);
    directory->Print();

    delete bitHdr;
    delete dirHdr;
    delete freeMap;
    delete directory;
} 
